package graph_viewer.structure.builder;

import java.io.*;
import java.util.*;

import graph_viewer.app_exception.*;
import graph_viewer.util.*;
import graph_viewer.structure.*;

// read node data from file stream, and create a generic tree
abstract public class Basic_Builder implements Graph_Builder{
	public void build_data( Graph a_graph, File a_file )  throws IOException{
		//
	}
	

	
	protected boolean is_valid_data_file( File a_file ){
		return a_file.exists() && a_file.canRead();
	}

	protected boolean is_node_start( String a_line ){
		return !( is_end_flag( a_line ) || is_comment_line( a_line ) || is_closed_graph_edge_start( a_line ) || is_closed_node_start( a_line ) );
	}

	protected boolean is_end_flag( String a_line ){
		return is_flag_start( a_line, this.end );
	}

	protected boolean is_comment_line( String a_line ){
		return is_flag_start( a_line, this.comments );
	}

	protected boolean is_closed_graph_edge_start( String a_line ){
		return is_flag_start( a_line, this.clustered_graph_edge_start );
	}

	protected boolean is_closed_node_start( String a_line ){
		return is_flag_start( a_line, this.clustered_node_start );
	}

	private boolean is_flag_start( String a_line, String tig ){
		return a_line.startsWith( tig );
	}
	
	//retrieve the lines following the cate_flag line from a text file.
	// the format a section of the file is the below:
	// Cate_Flag
	// fisrt line
	// seconde line
	//...
	// last line
	// # optional comments line
	// a blank line as the seperator between two sections                        
	// 
	// the end of the file is the finish mark ~

	protected ArrayList create_information_list_by_category( File a_file, String cate_flag ) {

		Debug.println( "=============create_information_list_by_category", 5 );
		ArrayList node_information_list	= new ArrayList();
		try{
			BufferedReader	node_data_reader	= new BufferedReader( new InputStreamReader( new FileInputStream( a_file ) ) );
			boolean
				is_end	= false,
				is_information_category_start	= false;
			
			while ( true ){
				String node_list_string = node_data_reader.readLine().trim() ;			
				Debug.println( "finding " + node_list_string , 5 );

				if ( is_end_flag(node_list_string  ) ){
					is_end	= true;
					break;
				}

				if ( node_list_string.startsWith( cate_flag ) ){					
					Debug.println( "found cate_flag: " + cate_flag, 5 );
					is_information_category_start	= true;
					break;
				}			
			}//end of while true

			if ( (! is_end ) && is_information_category_start ){
				while ( true ){
					String node_list_string = node_data_reader.readLine().trim() ;

					Debug.println( "creating  " + cate_flag + " is_information_category_start: " + node_list_string, 5 );
					
					//if ( node_list_string.length() == 0 ){// a blank line
					if ( is_section_finished( node_list_string ) ){// a blank line
						Debug.println( cate_flag + " is_information_category_ end" , 5 );
						break;
					}					
					

					if ( !is_comment_line( node_list_string ) ){
						Debug.println( node_list_string + " added.", 5 );
						node_information_list.add( node_list_string );
					}				

				}//end of while
			}// end of if ! is_end && is_information_category_start
			
		}catch ( IOException ioe ){
			Out.println( "IOException occured in create_information_list_by_category! \n" + ioe.toString() );
		}

		
		Debug.println( "=============create_information_list_by_category end===============",  5 );
			
		return node_information_list;
	}
	
	protected boolean is_section_finished( String a_line ){
		a_line.trim();

		return a_line.length() == 0;
	}

	//@a_pair	"a	b"
	//@return String[2]
	protected String[] parse_a_pair_of_word( String a_pair_of_word, String sep ){		

		String first_word, second_word;
		Debug.println( "parse_a_pair_of_word: |" + a_pair_of_word + "| by sep: |" + sep + "|.",  4 );

		if ( a_pair_of_word.trim().length() == 0 ){
			throw new App_Exception( "Try to parse a blank word." );
		}

		int	 sep_index	= a_pair_of_word.indexOf( sep );
		Debug.println( "sep_index create_parent_children_relation: " + sep_index,  4 );
		if ( sep_index > 0 ){
			first_word	= a_pair_of_word.substring( 0, sep_index ).trim();
			second_word	= a_pair_of_word.substring( sep_index+1 ).trim();			
		}else{
			first_word	= a_pair_of_word.trim();
			second_word	= a_pair_of_word.trim();				
		}		
		
		Debug.println( "parse_a_pair_of_word gets: first_word:" + first_word + ", second_word: " + second_word, 4 ) ;

		return new String[]{ first_word, second_word };
	}

	protected Node retrieve_node_by_label( String label, ArrayList nodes ){
		for ( Iterator _i = nodes.iterator(); _i.hasNext(); ){
			Node node	= (Node)_i.next();

			if ( node.get_label().equals( label ) ){
				return node;
			}
		}
		
		return null;
	}

}